/*
  SortTable
  version 2
  7th April 2007
  Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/

  Instructions:
  Download this file
  Add <script src="sorttable.js"></script> to your HTML
  Add class="sortable" to any table you'd like to make sortable
  Click on the headers to sort

  Thanks to many, many people for contributions and suggestions.
  Licenced as X11: http://www.kryogenix.org/code/browser/licence.html
  This basically means: do what you want with it.
*/

sorttable = {
  makeSortable: function(table) {
    if (table.getElementsByTagName('thead').length == 0) {
      // table doesn't have a tHead. Since it should have, create one and
      // put the first table row in it.
      var the = document.createElement('thead');
      the.appendChild(table.rows[0]);
      table.insertBefore(the,table.firstChild);
    }

    // work through each column and calculate its type
    var headrow = table.tHead.rows[0].cells;
    var	tbody = table.tBodies[0];
    for (var i = 0; i < headrow.length; i++) {
        if (i >= 3) break; // only 3 columns to sort
	headrow[i].sorttable_sortfunction =
		(i == 2) ? sorttable.sort_ipaddr : sorttable.sort_alpha;
	// make it clickable to sort
	headrow[i].addEventListener("click", function(e) {
	    var sortfwdind;
	    var sortrevind;
	    if (this.className.search(/\bsorttable_sorted\b/) != -1) {
		// if we're already sorted by this column, just
		// reverse the table, which is quicker
		sorttable.reverse(tbody);
		this.className = this.className.replace(
			'sorttable_sorted', 'sorttable_sorted_reverse');
		this.removeChild(document.getElementById(
			'sorttable_sortfwdind'));
		sortrevind = document.createElement('span');
		sortrevind.id = "sorttable_sortrevind";
		sortrevind.innerHTML = '&nbsp;&#x25B4;';
		this.appendChild(sortrevind);
		return;
	    }
	    if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) {
		// if we're already sorted by this column in reverse, just
		// re-reverse the table, which is quicker
		sorttable.reverse(tbody);
		this.className = this.className.replace(
			'sorttable_sorted_reverse', 'sorttable_sorted');
		this.removeChild(document.getElementById(
			'sorttable_sortrevind'));
		sortfwdind = document.createElement('span');
		sortfwdind.id = 'sorttable_sortfwdind';
		sortfwdind.innerHTML = '&nbsp;&#x25BE;';
		this.appendChild(sortfwdind);
		return;
	    }

	    // remove sorttable_sorted classes
	    var array = this.parentNode.childNodes;
	    for (var j = 0; j < array.length; j++) {
	        if (j >= 3) break; // only 3 cells need to do
		var cell = array[j];
		cell.className = cell.className
			.replace(/\bsorttable_sorted(_reverse)?\b/, '');
	    }
	    sortfwdind = document.getElementById('sorttable_sortfwdind');
	    if (sortfwdind)
		sortfwdind.parentNode.removeChild(sortfwdind);
	    sortrevind = document.getElementById('sorttable_sortrevind');
	    if (sortrevind)
		sortrevind.parentNode.removeChild(sortrevind);

	    this.className += ' sorttable_sorted';
	    sortfwdind = document.createElement('span');
	    sortfwdind.id = 'sorttable_sortfwdind';
	    sortfwdind.innerHTML = '&nbsp;&#x25BE;';
	    this.appendChild(sortfwdind);

	    // build an array to sort. This is a Schwartzian transform thing,
	    // i.e., we decorate each row with the actual sort key, sort based
	    // on the sort keys, and then put the rows back in order which is
	    // a lot faster because you only get innerText once per row
	    var row_array = [];
	    var i = this.cellIndex;
	    var rows = tbody.rows;
	    var len = rows.length;
	    for (var j = 0; j < len; j++) {
		row_array.push([rows[j].cells[i].innerText, rows[j]]);
	    }
	    row_array.sort(this.sorttable_sortfunction);

	    for (var j = 0; j < len; j++) {
		tbody.appendChild(row_array[j][1]);
	    }
	    delete row_array;
	}, false);
    }
  },

  reverse: function(tbody) {
    // reverse the rows in a tbody
    var newrows = [];
    for (var i = 0; i < tbody.rows.length; i++) {
      newrows[newrows.length] = tbody.rows[i];
    }
    for (var i = newrows.length - 1; i >= 0; i--) {
       tbody.appendChild(newrows[i]);
    }
    delete newrows;
  },

  /* each sort function takes two parameters, a and b
     you are comparing a[0] and b[0] */
  sort_ipaddr: function (a, b) {
    var a0 = a[0].replace(/\b(\d\d)\b/g,'0$1').replace(/\b(\d)\b/g,'00$1');
    var b0 = b[0].replace(/\b(\d\d)\b/g,'0$1').replace(/\b(\d)\b/g,'00$1');
    if (a0 == b0) return 0;
    if (a0 < b0) return -1;
    return 1;
  },
  sort_alpha: function (a, b) {
    if (a[0] == b[0]) return 0;
    if (a[0] < b[0]) return -1;
    return 1;
  }
}

